HAL SD initialization and configuration functions migration ¶
This section provides information about HAL SD initialization and configuration for STM32 HAL1 to HAL2 migration.
Open STM32CubeMX2 SD configuration panel.
Configure the SW layer HAL.
Configure the SD main features.
Configure the advanced SD features.
Configure the SD security and privilege features if needed.
Configure the SD GPIO pins.
Configure the NVIC if the application requires the SD to be used in IT mode.
Generate the code.
HAL SD configuration panel ¶
Create a new project with STM32CubeMX2, start by enabling the SDMMC1 instance as SD, as shown in this example with the selected SDMMC1, then start the initialization and the main configuration.
HAL SD main features configuration ¶
The bus width and transfer frequency are selected according to the SD card and SDMMC capabilities. The Clock Edge, Clock Power Save, and Hardware Flow Control options can be configured as needed. Users can either choose the default timeout values or set custom ones for data transmission and control operations.
HAL SD advanced features configuration ¶
The Delay Block can be configured and enabled under the advanced features section. This is recommended for high-speed SD operation and is available on supported STM32 series. Enable the Delay Block and choose the appropriate clock phase value to optimize timing and improve data throughput.
HAL SD security and privilege features configuration ¶
Configure the SD security and privilege features if needed.
GPIO configuration ¶
Configure GPIO pins.
NVIC configuration ¶
Configure the NVIC in case of an interrupt.
Generated SD initialization and de-initialization sequences ¶
The SD initialization sequence is generated in the
mx_sdmmc1_sd_init
function in
mx_sdmmc1.c
file under
$YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.
|
Topic |
HAL 1 Code Snippet |
HAL 2 Code Snippet |
|---|---|---|
|
Handle declaration |
SD_HandleTypeDef hsd_card;
|
static hal_sd_handle_t hSD;
|
|
Initialization and configuration sequence |
static void MX_SDMMC1_SD_Init(void)
{
hsd1.Instance = SDMMC1;
hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_FALLING;
hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
hsd1.Init.ClockDiv = 0;
if (HAL_SD_Init(&hsd1) != HAL_OK)
{
Error_Handler();
}
}
/* HAL_SD_MspInit callback called inside HAL_SD_Init */
void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hsd->Instance==SDMMC1)
{
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SDMMC1 GPIO Configuration
PC4 ------> SDMMC1_CMD
PC12 ------> SDMMC1_CK
PB13 ------> SDMMC1_D0
*/
GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_SDMMC1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SDMMC1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SDMMC1 interrupt Init */
HAL_NVIC_SetPriority(SDMMC1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
}
}
|
hal_sd_handle_t *mx_sdmmc1_sd_init(void)
{
hal_sd_config_t sd_config;
if (HAL_SD_Init(&hsd1, HAL_SD_CARD_1) != HAL_OK)
{
return NULL;
}
/* SD GPIO Configuration **************************************************/
HAL_RCC_GPIOC_EnableClock();
HAL_RCC_GPIOB_EnableClock();
hal_gpio_config_t gpio_config;
/**
SDMMC1 GPIO Configuration
[GPIO Pin] ------> [Signal Name]
PC12 ------> SDMMC1_CK
PC4 ------> SDMMC1_CMD
**/
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_11;
HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_12 | HAL_GPIO_PIN_4, &gpio_config);
/**
SDMMC1 GPIO Configuration
[GPIO Pin] ------> [Signal Name]
PB13 ------> SDMMC1_D0
**/
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_6;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_13, &gpio_config);
if (HAL_RCC_SDMMC1_SetKernelClkSource(HAL_RCC_SDMMC1_CLK_SRC_PLL) != HAL_OK)
{
return NULL;
}
HAL_RCC_SDMMC1_EnableClock();
sd_config.clk_cfg.clk_edge = HAL_SD_CLOCK_EDGE_FALLING;
sd_config.clk_cfg.clk_power_save = HAL_SD_CLOCK_POWER_SAVE_DISABLE;
sd_config.bus_wide = HAL_SD_BUS_WIDE_1BIT;
sd_config.hw_flow_ctrl = HAL_SD_HARDWARE_FLOW_CONTROL_DISABLE;
sd_config.transceiver = HAL_SD_TRANSCEIVER_NOT_PRESENT;
sd_config.data_timeout_cycle = HAL_SD_DATA_MAX_TIMEOUT;
sd_config.stop_xfer_timeout_ms = HAL_SD_STOP_XFER_MAX_TIMEOUT;
sd_config.erase_timeout_ms = HAL_SD_ERASE_MAX_TIMEOUT;
if (HAL_SD_SetConfig(&hsd1, &sd_config) != HAL_OK)
{
return NULL;
}
if (HAL_SD_SetFifoThreshold(&hSDMMC1, HAL_SD_FIFO_THRESHOLD_NOT_USED) != HAL_OK)
{
return NULL;
}
/* Enable the interruption for SD */
HAL_CORTEX_NVIC_SetPriority(SDMMC1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
HAL_CORTEX_NVIC_EnableIRQ(SDMMC1_IRQn);
return &hsd1;
}
|
|
Deinitialization sequence |
/* User should call the HAL_SD_DeInit() function */
/* HAL_SD_MspDeInit is called inside HAL_SD_DeInit function */
void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
{
if(hsd->Instance==SDMMC1)
{
/* USER CODE BEGIN SDMMC1_MspDeInit 0 */
/* USER CODE END SDMMC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SDMMC1_CLK_DISABLE();
/**SDMMC1 GPIO Configuration
PC4 ------> SDMMC1_CMD
PC12 ------> SDMMC1_CK
PB13 ------> SDMMC1_D0
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4 | GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13);
/* SDMMC1 interrupt DeInit */
HAL_NVIC_DisableIRQ(SDMMC1_IRQn);
/* USER CODE BEGIN SDMMC1_MspDeInit 1 */
/* USER CODE END SDMMC1_MspDeInit 1 */
}
}
|
void mx_sdmmc1_sd_deinit(void)
{
(void)HAL_SD_DeInit(&hSDMMC1);
HAL_RCC_SDMMC1_Reset();
HAL_RCC_SDMMC1_DisableClock();
/* De-initialize all GPIO pins associated with SDMMC1 */
HAL_GPIO_DeInit(HAL_GPIOC, HAL_GPIO_PIN_4 | HAL_GPIO_PIN_12);
HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_13);
#if defined(USE_HAL_GPIO_HSLV) && (USE_HAL_GPIO_HSLV == 1U)
HAL_GPIO_DisableHighSpeedLowVoltage(HAL_GPIOC, HAL_GPIO_PIN_4 | HAL_GPIO_PIN_12);
#endif /* USE_HAL_GPIO_HSLV */
#if defined(USE_HAL_GPIO_HSLV) && (USE_HAL_GPIO_HSLV == 1U)
HAL_GPIO_DisableHighSpeedLowVoltage(HAL_GPIOB, HAL_GPIO_PIN_13);
#endif /* USE_HAL_GPIO_HSLV */
}
|
|
HAL1 / HAL2 Code Snippet |
|---|
void SDMMC1_IRQHandler(void)
{
HAL_SD_IRQHandler(&hsd1);
}
|